R Wheel Running Analysis

Welcome!

This is a Quarto document built to help you analyze .log files from mouse wheel running experiments.

How to use this notebook:

  1. Set your ⚙ options for analysis
  2. Run code chunks 1-3 to set up and create your folder structure.
  3. Dump all the .log files in the folder created by the script in data > 01_Raw_data.
  4. Then run the remaining code chunks in order.
  5. To run everything at once and produce a nice HTML output, Click the Render button above

When you execute code within the notebook, the results appear beneath the code. You can run code chunks one by one by clicking the Run button in the upper right corner of the chunk or by placing your cursor the code chunk and pressing Ctrl+Shift+Enter. To run all code chunks, you can Ctrl+Alt+R or hit the Run button and select “Run All” or “Restart R and Run all.”

📚 Setup Libraries

This code block loads necessary libraries and sets up the directory structure necessary for the project. You need to run it, but it is not included in your output notebook.

⚙ Options for analysis – USER INPUT REQUIRED

  • Select your options for your analysis in the code below. TRUE for True, FALSE for False.
Settings for Exp1 : 
      Experiment name : Exp1 
           Lights On  : 7 
           Lights Off : 19 
         Time change? : FALSE 


  ~ DONE! ~  02. Settings loaded! 

📁 Make directory structure for the project


 ~ DONE! ~ 3. Made folder structure here:  /Users/rsenft/Documents/GitHub/Mouse-Wheel-Running-Analysis

đŸ§č Organize, Load, and Clean Data

This step organizes the mouse .log files into 1 folder per mouse, then loads the data into R and creates a metadata table from the data frames.

If you’d like to remove animals, now is the time to remove those folders from data > 02_Organized_data.

❓Optional: Fix incorrect metadata

If you’d like to change metadata in your experiment, you can do so in these two code cells. The first is designed specifically for genotype. You can replace original_name with whatever genotype you want to replace and new_name with whatever you want the new genotype to be.

print("Here are the original genotypes in your current experiment:")
[1] "Here are the original genotypes in your current experiment:"
print(unique(full_metadata$Genotype))
[1] "con"   "exp"   "N-con" "N-exp"
# Replace?
# full_metadata[Genotype=="original_name",Genotype:="new_name"]

full_metadata[Genotype=="N-con",Genotype:="con"]
full_metadata[Genotype=="N-exp",Genotype:="exp"]

print("Here are the genotypes in your current experiment AFTER replacement:")
[1] "Here are the genotypes in your current experiment AFTER replacement:"
print(unique(full_metadata$Genotype))
[1] "con" "exp"

This block will make all Sex values uppercase. Don’t run this if you don’t have a column called “Sex” in full_metadata

This block is for more intense editing of mice (e.g., you made a mistake with one mouse and need to modify it). After running this cell a popup will appear in which you can edit anything in your metadata table. Depending on the number of mice, this could be slow.

Use this block to check the metadata and if necessary, you can re-run the previous code blocks.

print(full_metadata)
              MouseName        Date StartTime bin_secs CageNum Genotype Sex
 1:                626A 01-mar-2022     12:58       10  cage-1      con   M
 2:                627A 01-mar-2022     12:58       10  cage-2      exp   M
 3:                629A 01-mar-2022     12:58       10  cage-3      con   F
 4:                630A 01-mar-2022     12:58       10  cage-4      exp   F
 5:                680A 01-mar-2022     12:58       10  cage-5      exp   F
 6:                682A 01-mar-2022     12:58       10  cage-6      con   F
 7:                685A 01-mar-2022     12:58       10  cage-7      con   M
 8:                686A 01-mar-2022     12:58       10  cage-8      exp   M
 9:                689A 01-mar-2022     12:58       10  cage-9      con   F
10:                691A 01-mar-2022     12:58       10 cage-10      exp   F
11:                692A 01-mar-2022     12:58       10 cage-11      exp   F
12:                693A 01-mar-2022     12:58       10 cage-12      con   F
13:                696A 01-mar-2022     12:58       10 cage-13      exp   M
14:                698A 01-mar-2022     12:58       10 cage-14      con   M
15:                700A 01-mar-2022     12:58       10 cage-15      exp   F
16:                701A 01-mar-2022     12:58       10 cage-16      con   F
17:                702A 01-mar-2022     12:58       10 cage-17      con   F
18:                703A 01-mar-2022     12:58       10 cage-18      exp   F
19:                711A 01-mar-2022     12:58       10 cage-19      exp   M
20:                712A 01-mar-2022     12:58       10 cage-20      exp   M
21:                713A 01-mar-2022     12:58       10 cage-21      con   M
22:                714A 01-mar-2022     12:58       10 cage-22      con   M
23:                716A 01-mar-2022     12:58       10 cage-23      exp   F
24:                717A 01-mar-2022     12:58       10 cage-24      con   F
25:            OA3-139k 18-jun-2021     15:27       10  cage-3      con   F
26:            OA4-140k 18-jun-2021     15:27       10  cage-4      con   F
27:            OA5-141k 18-jun-2021     15:27       10  cage-5      exp   F
28: OA5-347K-2021-10-01 01-oct-2021     13:04       10  cage-5      con   M
29:            OA6-142k 18-jun-2021     15:27       10  cage-6      exp   F
30: OA6-348K-2021-10-01 01-oct-2021     13:04       10  cage-6      exp   M
31:            OA7-143k 18-jun-2021     15:27       10  cage-7      exp   F
32: OA7-448K-2021-10-01 01-oct-2021     13:04       10  cage-7      con   F
33: OA8-449K-2021-10-01 01-oct-2021     13:04       10  cage-8      exp   F
              MouseName        Date StartTime bin_secs CageNum Genotype Sex
                          id
 1:                626A|Exp1
 2:                627A|Exp1
 3:                629A|Exp1
 4:                630A|Exp1
 5:                680A|Exp1
 6:                682A|Exp1
 7:                685A|Exp1
 8:                686A|Exp1
 9:                689A|Exp1
10:                691A|Exp1
11:                692A|Exp1
12:                693A|Exp1
13:                696A|Exp1
14:                698A|Exp1
15:                700A|Exp1
16:                701A|Exp1
17:                702A|Exp1
18:                703A|Exp1
19:                711A|Exp1
20:                712A|Exp1
21:                713A|Exp1
22:                714A|Exp1
23:                716A|Exp1
24:                717A|Exp1
25:            OA3-139k|Exp1
26:            OA4-140k|Exp1
27:            OA5-141k|Exp1
28: OA5-347K-2021-10-01|Exp1
29:            OA6-142k|Exp1
30: OA6-348K-2021-10-01|Exp1
31:            OA7-143k|Exp1
32: OA7-448K-2021-10-01|Exp1
33: OA8-449K-2021-10-01|Exp1
                          id

🔱 Add columns to data

This chunk takes your data for each mouse and adds additional variables, like speed, time of day, and experimental phase information. Data columns include:

  • expDay (1, 2, 3
# of experimental days)
  • speed (should be in meters/min)
  • elapsedDays same as expDay but days can be fractional
  • hour (clock time hour)
  • minutes (clock time minutes)
  • activeFactor (whether the animal is in its active phase (lights OFF -> TRUE))
  • t (time in seconds since the first lights ON (can precede the start of the recording, usually this is lights on on Day 1)
  • expPhase (which experimental phase each time point belongs to)
  • moving (whether that individual animal moved during that 10 second period))

Now we stitch everything together into 1 big data table. We additionally add an id variable for each experimental mouse that is the mouse ID + the experiment name.

behavr table with: 33 individuals 7 metavariables 10 variables 2.911903e+06 measurements 1 key (id)

~ DONE! ~ 7. 0 mice were removed because they ran less than 1% of the experiment:

📆 Experimental timeline

Now we add in the different phases of the experiment in a expPhase column.

~ DONE! ~ 8. Phase information added to data table. 📋

đŸ’Ÿ Save tables

This is optional, if you want to save out tables of binned data for each mouse.

# Would you like to save data every X min? (default True)
saveBinned <- TRUE
desired_bin <- 5 # min

#######################
#Save Metadata table
write.csv(full_metadata, file=here(dir_results, "exp_metdata.csv"))


#Save daily and light cycle data for every mouse
  dt_daily_byLC <- dt %>% dplyr::group_by(id, expDay, activeFactor) %>% dplyr::summarize(avg_speed = mean(speed))
`summarise()` has grouped output by 'id', 'expDay'. You can override using the
`.groups` argument.
    filename <- paste0(expName,"_daily_bylightcycle.csv")
    write.csv(dt_daily_byLC, file=here(dir_results, filename), row.names = FALSE)

#Save just daily data for every mouse
  dt_daily <- dt %>% dplyr::group_by(id, expDay) %>% dplyr::summarize(avg_speed = mean(speed))
`summarise()` has grouped output by 'id'. You can override using the `.groups`
argument.
    filename <- paste0(expName,"_daily.csv")
    write.csv(dt_daily, file=here(dir_results, filename), row.names = FALSE)
  cat(cmark, paste0('9. Finished summarizing daily data for ',nMice,' mice '), '🐁')
~ DONE! ~ 9. Finished summarizing daily data for 33 mice  🐁
if (saveBinned){
  pb <- progress_bar$new(total=nMice)
for (eachid in metadata[,id]){
  df <- full_dt[id==eachid,]
  mouse <- sub("\\|.*", "", eachid)
  t_min <- min(df$t)/behavr::mins(1)
  t_max <- max(df$t)/behavr::mins(1)
  df <- data.frame("MeanSpeed"=tapply(df$speed, cut(df$t/behavr::mins(1), seq(t_min, t_max, by=desired_bin)), mean), "ExpDay"=tapply(df$expDay, cut(df$t/behavr::mins(1), seq(t_min, t_max, by=desired_bin)), median))
  filename <- paste0(mouse,"_",desired_bin,"_min.csv")
  write.csv(df, file=here(dir_table_ind, filename), row.names = F)
  pb$tick()
}

cat('\n', cmark, '9. Finished collapsing data into ',desired_bin,' minute bins (function = mean) for ',nMice,' mice ', '🐁')
}

 ~ DONE! ~ 9. Finished collapsing data into  5  minute bins (function = mean) for  33  mice  🐁
#remove(full_dt)
startDay <- 1
endDay <- max(dt$expDay)

📈 Make graphs

source(here(dir_scripts, "graph_functions.R"))

#color_palette = c("#4ECDC4", "#FF6B6B") #red and blue
color_palette=c("#00BBF9","#FDCA40", "#F05365") #yellow and blue

Bout analysis

Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

Raw activity for each individual mouse

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Saving 15 x 4 in image

Polar activity plot

Saving 7 x 5 in image
Saving 7 x 5 in image

Actogram graph for all mice

Saving 7 x 10 in image

Periodogram

Warning: The following aesthetics were dropped during statistical transformation: peak
â„č This can happen when ggplot fails to infer the correct grouping structure in
  the data.
â„č Did you forget to specify a `group` aesthetic or to convert a numerical
  variable into a factor?
Saving 7 x 5 in image
Warning: The following aesthetics were dropped during statistical transformation: peak
â„č This can happen when ggplot fails to infer the correct grouping structure in
  the data.
â„č Did you forget to specify a `group` aesthetic or to convert a numerical
  variable into a factor?

Warning: The following aesthetics were dropped during statistical transformation: peak
â„č This can happen when ggplot fails to infer the correct grouping structure in
  the data.
â„č Did you forget to specify a `group` aesthetic or to convert a numerical
  variable into a factor?
Saving 7 x 5 in image
Warning: The following aesthetics were dropped during statistical transformation: peak
â„č This can happen when ggplot fails to infer the correct grouping structure in
  the data.
â„č Did you forget to specify a `group` aesthetic or to convert a numerical
  variable into a factor?

Percent time running

hex_colors <- c("#f8766d", "#7cae00", "#00bfc4", "#c77cff")

for (phase in phase_df$phase){
  dt_sub <- dt[expPhase==phase,]
  phaseforfilename <- str_replace_all(phase, ":", "-")
  summary_dt <- rejoin(dt_sub[,
           .(
             # this is where the computation happens
             phase_moving_fraction = mean(moving),
             active_moving_fraction = mean(moving[activeFactor],na.rm=TRUE),
             inactive_moving_fraction = mean(moving[!activeFactor],na.rm=TRUE)
             ),
           by=id])
  # by sex and genotype
  pretty_boxplot(summary_dt, x_var="Sex", y_var="phase_moving_fraction", fill_color="Genotype", savename = paste0(phaseforfilename, "_percent_time_running_geno.png"), title=phase, color_palette=color_palette, y_lab="Percent time running", axis_scale="percent")

  # by genotype

  pretty_boxplot(summary_dt, x_var="Genotype", y_var="phase_moving_fraction", fill_color="Genotype", savename = paste0(phaseforfilename, "_percent_time_running_geno.png"), title=phase, color_palette=color_palette, y_lab="Percent time running", axis_scale="percent")

  setnames(summary_dt, "phase_moving_fraction", paste0(phase,"_moving_fraction"))
  write.csv(summary_dt, file=here(dir_results, paste0(phaseforfilename,"_percent_time_running.csv")))

  
  # by sex and genotype and light cycle

  summary_dt_long <- summary_dt %>% 
    select(-c(paste0(phase, "_moving_fraction"))) %>% 
    dplyr::rename("overall_moving_fraction"="moving_fraction") %>%
    pivot_longer(cols = ends_with("_moving_fraction"), names_to="Cycle", values_to = "cycle_moving_fraction", names_pattern = "(.*)_moving_fraction")
  
  pretty_facet_graph(summary_dt_long, x_var="Genotype", y_var="cycle_moving_fraction", grid_row_var="Cycle", grid_col_var="Sex")
}
Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

Saving 7 x 5 in image

📑 Methods and References

Analyses were conducted using the R Statistical language (version 4.1.1; R Core Team, 2021) on macOS Big Sur 10.16, using the packages matrixStats (version 0.61.0; Bengtsson H, 2021), ggbeeswarm (version 0.7.1; Clarke E et al., 2022), progress (version 1.2.2; CsĂĄrdi G, FitzJohn R, 2019), data.table (version 1.14.2; Dowle M, Srinivasan A, 2021), sleepr (version 0.3.0; Geissmann Q, 2018), behavr (version 0.3.2; Geissmann Q, 2019), ggetho (version 0.3.6; Geissmann Q, 2020), zeitgebr (version 0.3.5; Geissmann Q, Garcia L, 2020), vroom (version 1.6.0; Hester J et al., 2022), fs (version 1.5.2; Hester J et al., 2021), report (version 0.5.5; Makowski D et al., 2021), here (version 1.0.1; MĂŒller K, 2020), reshape2 (version 1.4.4; Wickham H, 2007), ggplot2 (version 3.4.0; Wickham H, 2016), stringr (version 1.4.0; Wickham H, 2019), dplyr (version 1.0.8; Wickham H et al., 2022), tidyr (version 1.2.0; Wickham H, Girlich M, 2022) and colorspace (version 2.0.3; Zeileis A et al., 2020).

References

  • Bengtsson H (2021). matrixStats: Functions that Apply to Rows andColumns of Matrices (and to Vectors). R package version 0.61.0, <URL:https://CRAN.R-project.org/package=matrixStats>.
  • Clarke E, Sherrill-Mix S, Dawson C (2022). ggbeeswarm: CategoricalScatter (Violin Point) Plots. R package version 0.7.1, <URL:https://CRAN.R-project.org/package=ggbeeswarm>.
  • CsĂĄrdi G, FitzJohn R (2019). progress: Terminal Progress Bars. Rpackage version 1.2.2, <URL:https://CRAN.R-project.org/package=progress>.
  • Dowle M, Srinivasan A (2021). data.table: Extension of data.frame.R package version 1.14.2, <URL:https://CRAN.R-project.org/package=data.table>.
  • Geissmann Q (2018). sleepr: Analyse Activity and Sleep Behaviour. Rpackage version 0.3.0, <URL:https://CRAN.R-project.org/package=sleepr>.
  • Geissmann Q (2019). behavr: Canonical Data Structure for BehaviouralData. R package version 0.3.2, <URL:https://CRAN.R-project.org/package=behavr>.
  • Geissmann Q (2020). ggetho: Visualisation of High-ThroughputBehavioural (i.e. Ethomics) Data. R package version 0.3.6, <URL:https://CRAN.R-project.org/package=ggetho>.
  • Geissmann Q, Garcia L (2020). zeitgebr: Analysis of CircadianBehaviours. R package version 0.3.5, <URL:https://CRAN.R-project.org/package=zeitgebr>.
  • Hester J, Wickham H, Bryan J (2022). vroom: Read and Write RectangularText Data Quickly. R package version 1.6.0, <URL:https://CRAN.R-project.org/package=vroom>.
  • Hester J, Wickham H, CsĂĄrdi G (2021). fs: Cross-Platform File SystemOperations Based on ‘libuv’. R package version 1.5.2, <URL:https://CRAN.R-project.org/package=fs>.
  • Makowski D, Ben-Shachar M, Patil I, LĂŒdecke D (2021). “AutomatedResults Reporting as a Practical Tool to Improve Reproducibility andMethodological Best Practices Adoption.” CRAN. <URL:https://github.com/easystats/report>.
  • MĂŒller K (2020). here: A Simpler Way to Find Your Files. R packageversion 1.0.1, <URL: https://CRAN.R-project.org/package=here>.
  • R Core Team (2021). R: A Language and Environment for StatisticalComputing. R Foundation for Statistical Computing, Vienna, Austria.<URL: https://www.R-project.org/>.
  • Wickham H (2007). “Reshaping Data with the reshape Package.” Journalof Statistical Software, 21(12), 1-20. <URL:http://www.jstatsoft.org/v21/i12/>.
  • Wickham H (2016). ggplot2: Elegant Graphics for Data Analysis.Springer-Verlag New York. ISBN 978-3-319-24277-4, <URL:https://ggplot2.tidyverse.org>.
  • Wickham H (2019). stringr: Simple, Consistent Wrappers for CommonString Operations. R package version 1.4.0, <URL:https://CRAN.R-project.org/package=stringr>.
  • Wickham H, François R, Henry L, MĂŒller K (2022). dplyr: A Grammar ofData Manipulation. R package version 1.0.8, <URL:https://CRAN.R-project.org/package=dplyr>.
  • Wickham H, Girlich M (2022). tidyr: Tidy Messy Data. R packageversion 1.2.0, <URL: https://CRAN.R-project.org/package=tidyr>.
  • Zeileis A, Fisher JC, Hornik K, Ihaka R, McWhite CD, Murrell P,Stauffer R, Wilke CO (2020). “colorspace: A Toolbox for Manipulatingand Assessing Colors and Palettes.” Journal of Statistical Software,96(1), 1-49. doi: 10.18637/jss.v096.i01 (URL:https://doi.org/10.18637/jss.v096.i01).Zeileis A, Hornik K, Murrell P (2009). “Escaping RGBland: SelectingColors for Statistical Graphics.” Computational Statistics & DataAnalysis, 53(9), 3259-3270. doi: 10.1016/j.csda.2008.11.033 (URL:https://doi.org/10.1016/j.csda.2008.11.033).Stauffer R, Mayr GJ, Dabernig M, Zeileis A (2009). “Somewhere over theRainbow: How to Make Effective Use of Colors in MeteorologicalVisualizations.” Bulletin of the American Meteorological Society,96(2), 203-216. doi: 10.1175/BAMS-D-13-00155.1 (URL:https://doi.org/10.1175/BAMS-D-13-00155.1).

Session info for configuration

R version 4.1.1 (2021-08-10) Platform: x86_64-apple-darwin17.0 (64-bit) Running under: macOS Big Sur 10.16

Matrix products: default BLAS: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.0.dylib LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib

locale: [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages: [1] grid stats graphics grDevices utils datasets methods
[8] base

other attached packages: [1] ggbeeswarm_0.7.1 zeitgebr_0.3.5 sleepr_0.3.0 report_0.5.5
[5] ggetho_0.3.6 behavr_0.3.2 ggplot2_3.4.0 data.table_1.14.2 [9] progress_1.2.2 fs_1.5.2 vroom_1.6.0 dplyr_1.0.8
[13] reshape2_1.4.4 matrixStats_0.61.0 stringr_1.4.0 here_1.0.1
[17] tidyr_1.2.0 colorspace_2.0-3

loaded via a namespace (and not attached): [1] Rcpp_1.0.8.3 prettyunits_1.1.1 assertthat_0.2.1 rprojroot_2.0.3
[5] digest_0.6.29 utf8_1.2.2 R6_2.5.1 plyr_1.8.7
[9] evaluate_0.15 pracma_2.4.2 pillar_1.7.0 rlang_1.0.6
[13] rstudioapi_0.13 rmarkdown_2.13 labeling_0.4.2 htmlwidgets_1.5.4 [17] bit_4.0.4 munsell_0.5.0 compiler_4.1.1 vipor_0.4.5
[21] xfun_0.30 pkgconfig_2.0.3 htmltools_0.5.2 insight_0.18.7
[25] tidyselect_1.2.0 tibble_3.1.8 fansi_1.0.3 crayon_1.5.1
[29] tzdb_0.3.0 withr_2.5.0 jsonlite_1.8.0 gtable_0.3.0
[33] lifecycle_1.0.3 DBI_1.1.2 magrittr_2.0.3 scales_1.2.0
[37] datawizard_0.6.3 cli_3.4.1 stringi_1.7.6 farver_2.1.0
[41] ellipsis_0.3.2 generics_0.1.2 vctrs_0.5.1 RColorBrewer_1.1-3 [45] tools_4.1.1 bit64_4.0.5 glue_1.6.2 beeswarm_0.4.0
[49] purrr_0.3.4 hms_1.1.1 parallel_4.1.1 fastmap_1.1.0
[53] yaml_2.3.5 knitr_1.38